﻿'This class allows only numbers, CTRL+V, CTRL+C, Delete, R, and ALT buttons to be used.
'It cannot filter out ALT codes however :(
Imports System.Text.RegularExpressions
Public Class NumberOnlyTextbox
    Inherits TextBox
    Protected m_ctrl As TextBox
    Protected m_throw As KeyEventHandler
    Protected m_AllowMinus As Boolean
    Protected m_AllowDecimalsPoint As Boolean
    Public Sub New(ByRef ctrl As TextBox, ByRef AllowDecimalsPoint As Boolean, ByRef AllowMinus As Boolean, ByRef throwb As KeyEventHandler)
        ' Pass a reference to the textbox
        m_ctrl = ctrl
        ' Are Decimal Points allowed through
        m_AllowDecimalsPoint = AllowDecimalsPoint
        ' Are minus allowed through
        m_AllowMinus = AllowMinus
        ' Pass a reference to the delegate. (This is AddressOf a sub which further process the keypress.)
        m_throw = throwb
        ' Add an handler for the keydown event
        AddHandler m_ctrl.KeyDown, AddressOf M_onkeydown
    End Sub
    Protected Sub M_onkeydown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
        e.SuppressKeyPress = False
        Select Case e.KeyCode
            Case Keys.D0 To Keys.D9, Keys.NumPad0 To Keys.NumPad9
                If m_throw IsNot Nothing Then m_throw.Invoke(sender, e)
                Helpdesk.errorProvider.SetError(sender, "")
            Case Keys.Delete, Keys.Back, Keys.Enter, Keys.Return, Keys.Left, Keys.Right, Keys.Tab
                ' Allow "STANDARD" editting keys
                If m_throw IsNot Nothing Then m_throw.Invoke(sender, e)
                Helpdesk.errorProvider.SetError(sender, "")
            Case e.Modifiers = Keys.Control And Keys.V
                If Regex.IsMatch(My.Computer.Clipboard.GetText(), "^[0-9]+$") Then
                    m_throw.Invoke(sender, e)
                    Helpdesk.errorProvider.SetError(sender, "")
                Else
                    e.Handled = True
                    e.SuppressKeyPress = True
                    Helpdesk.errorProvider.SetError(sender, "Numeric characters only")
                End If
            Case e.Modifiers = Keys.Control And Keys.C
                m_throw.Invoke(sender, e)
                Helpdesk.errorProvider.SetError(sender, "")
            Case Else
                If e.KeyCode = Keys.ControlKey AndAlso Keys.V Or e.KeyCode = Keys.ControlKey AndAlso Keys.C Then
                Else
                    ' Supress all other key.
                    e.Handled = True
                    e.SuppressKeyPress = True
                    Helpdesk.errorProvider.SetError(sender, "Numeric characters only")
                End If
        End Select
    End Sub
End Class
